﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SmartCommunity.Models;
using System;
using System.Dynamic;

namespace SmartCommunity.WebApi.Controllers
{
    [AllowAnonymous]
    [Route("api/[controller]")]
    [ApiController]
    public class OptionController : ControllerBase
    {
        #region 构造函数
        private readonly SCDBContext ctx;
        public OptionController(SCDBContext ctx)
        {
            this.ctx = ctx;
        }
        #endregion

        #region 操作类型
        [HttpGet("operate-type")]
        public List<SelectOption> OperateTypeOptions([FromQuery] SelectOptionQuery query)
        {
            var options = Enum.GetValues<OperateType>().Select(a => new SelectOption((int)a, a.GetDescription()));
            return FilterSelectOptions(options, query);
        }
        #endregion

        #region 社区档案 
        [HttpGet("community")]
        public async Task<List<SelectOption>> SelectCommunity([FromQuery] SelectOptionQuery query)
        {
            var communitys = await ctx.Communities.ToListAsync();
            var options = communitys.Select(a => new SelectOption(a.CommunityId, a.CommunityName, a.Disabled));
            return FilterSelectOptions(options, query);
        }
        [HttpGet("area")]
        public async Task<List<SelectOption>> SelectArea([FromQuery] SelectOptionQuery query)
        {
            var areas = await ctx.Areas.Include(a => a.Community).ToListAsync();
            var options = areas.Select(a => new SelectOption(a.AreaId, a.AreaName, a.Disabled, a.CommunityName));
            return FilterSelectOptions(options, query);
        }
        [HttpGet("room")]
        public async Task<List<SelectOption>> SelectAreaRooms([FromQuery] SelectOptionQuery query)
        {
            if (query.AreaId == Guid.Empty) throw new Exception("必须传入小区ID参数");
            var areas = await ctx.Rooms.Include(a => a.Building).Where(a => a.Building.AreaId == query.AreaId).ToListAsync();
            var options = areas.Select(a => new SelectOption(a.RoomId, a.RoomCode, false, a.Building.BuildingName));
            return FilterSelectOptions(options, query);
        }
        #endregion

        #region 楼宇类型 
        [HttpGet("building-dicts")]
        public async Task<ActionResult> SelectBuildingEnums()
        {
            var types = new string[] { "BuildingLevel", "BuildingType", "BuildingUsage", "BuildingDirection" };
            var dicts = await ctx.Dicts.Include(a => a.DictItems).Where(a => types.Contains(a.DictType)).ToListAsync();
            var a = new
            {
                BuildingLevel = dicts.Single(a => a.DictType == "BuildingLevel").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
                BuildingType = dicts.Single(a => a.DictType == "BuildingType").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
                BuildingUsage = dicts.Single(a => a.DictType == "BuildingUsage").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
                BuildingDirection = dicts.Single(a => a.DictType == "BuildingDirection").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
            };
            return Ok(a);
        }
        [HttpGet("room-dicts")]
        public async Task<ActionResult> SelectRoomEnums()
        {
            var types = new string[] { "RoomType", "RoomState", "RoomUsage", "RoomDeco" };
            var dicts = await ctx.Dicts.Include(a => a.DictItems).Where(a => types.Contains(a.DictType)).ToListAsync();
            var a = new
            {
                RoomType = dicts.Single(a => a.DictType == "RoomType").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
                RoomState = dicts.Single(a => a.DictType == "RoomState").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
                RoomUsage = dicts.Single(a => a.DictType == "RoomUsage").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
                RoomDeco = dicts.Single(a => a.DictType == "RoomDeco").DictItems.Select(a => new SelectOption(int.Parse(a.DictValue), a.DictLabel)).ToArray(),
            };
            return Ok(a);
        }
        #endregion

        #region 数据字典
        [HttpGet("dict/{type}")]
        public async Task<ActionResult> SelectDictOptions(string type)
        {
            var dict = await ctx.Dicts.Include(a => a.DictItems).SingleOrDefaultAsync(a => a.DictType == type);
            if (dict == null) return UnprocessableEntity("找不到对应的数据字典：" + type);
            var data = dict.DictItems.Select(a => new SelectOption(a.DictValue, a.DictLabel, a.Disabled, a.DictCode));
            return Ok(data);
        }
        #endregion
        private static List<SelectOption> FilterSelectOptions(IEnumerable<SelectOption> options, SelectOptionQuery query)
        {
            var filterOptions = options;
            if (query.Disabled.HasValue)
            {
                options = options.Where(a => a.Disabled == query.Disabled.Value);
            }
            if (!string.IsNullOrWhiteSpace(query.Search))
            {
                options = options.Where(a => a.Label.Contains(query.Search.Trim()));
            }
            return options.ToList();
        }
    }

    public class SelectOptionQuery
    {
        /// <summary>
        /// 作废状态
        /// </summary>
        public bool? Disabled { get; set; }

        /// <summary>
        /// 模糊查询
        /// </summary>
        public string? Search { get; set; }

        public Guid? AreaId { get; set; }
    }

}
